# _*_ coding:utf-8 _*_
__author__ = 'joker_wb'
__date__ = '2018/4/20 12:23'

from numpy import *
import operator
import matplotlib.pyplot as plt
import os
def createDateSet():
    """
    生成数据和标签。
    :return:
    """
    data=array([[1,1.1],[1.,1.],[0.,0.],[0.,0.1]])
    labels=['A','A','B','B']
    return data,labels


def classfiy(inX,dataSet,labels,k):
    """
    数据分类
    :param inX:
    :param dataSet:
    :param labels:
    :param k:
    :return:
    """
    dataShape=dataSet.shape[0]
    diff=tile(inX,(dataShape,1))-dataSet
    sqDiff=diff**2
    sumDiff=sqDiff.sum(axis=1)

    sortedDistance=sumDiff.argsort()#输出从小到大

    classcount={}
    for i in range(k):
        voteIlabel=labels[sortedDistance[i]]
        classcount[voteIlabel]=classcount.get(voteIlabel,0)+1
    sortedclassCount=sorted(classcount.items(),key=operator.itemgetter(1),reverse=True)
    # print(sortedclassCount)
    return sortedclassCount[0][0]


def file2Matrix(filename):
    """
    从txt里面读取数据。
    :param filename:
    :return:
    """
    fr=open(filename)
    arrayOlines=fr.readlines()
    numbersOflines=len(arrayOlines)
    returnMat=zeros((numbersOflines,3))
    classLabelVector=[]
    index=0
    for line in arrayOlines:
        line=line.strip() #截取回车字符，如果不加的话，会有换行。
        listFromLine=line.split('\t')
        # print(line)
        returnMat[index,:]=listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index+=1
    return returnMat , classLabelVector

def photo2Vector(filename):
    """
    将txt文件转成1024向量
    :param filename:
    :return:
    """
    fr=open(filename)
    returnVect=zeros((1,1024))
    for i in range(32):
        lineStr=fr.readline()
        for j in range(32):
            returnVect[0,32*i+j]=int(lineStr[j])
    return returnVect

def autoNorm(dataSet):
    """
    对数据进行归一化。
    :param dataSet:
    :return:
    """
    minVals=dataSet.min(0)
    maxVals=dataSet.max(0)
    ranges=maxVals-minVals
    normdataSet=zeros(shape(dataSet))
    m=dataSet.shape[0]
    normdataSet=dataSet-tile(minVals,(m,1))
    normdataSet=normdataSet/tile(ranges,(m,1))
    return normdataSet,ranges,minVals

def datingClassTest():
    """
    测试函数。选取一定量的测试集，来测试准确率。
    :return:
    """
    hoRatio=0.10
    datingDateMat,datingLabels=file2Matrix('datingTestSet2.txt')
    normMat,ranges,minVals=autoNorm(datingDateMat)
    m=normMat.shape[0]
    numTestVecs=int(m*hoRatio)
    errorCount=0.0
    for i in range(numTestVecs):
        classifierResult=classfiy(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
        print('the classifier came back with',classifierResult,'the real answer is ',datingLabels[i])
        if(classifierResult!=datingLabels[i]):
            errorCount+=1.0

    print('the total error rate is ',(errorCount)/(float(numTestVecs)))

def classifierPerson():
    resultList=['not at all','in small doses','in large doses']
    ffMiles = float(input('一年挣多少钱？'))
    percentTats=float(input('花在打游戏上面的时间有多少？'))
    iceCream=float(input('一年吃多少雪糕？'))
    datingDataMat,datingLabels=file2Matrix('datingTestSet2.txt')
    normMat,range,minVals=autoNorm(datingDataMat)
    inArr=array([ffMiles,percentTats,iceCream])

    classifierResult=classfiy((inArr-minVals)/range,normMat,datingLabels,3)
    print('you will probably like this person:',resultList[classifierResult-1])


def handwritingClassTest():
    hwLabels=[]
    trainingFileList=os.listdir('trainingDigits')
    m=len(trainingFileList)
    trainingMat=zeros((m,1024))
    for i in range(m):
        fileNameStr=trainingFileList[i]
        fileStr=fileNameStr.split('.')[0]
        classNumStr=int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        trainingMat[i,:]=photo2Vector('trainingDigits/'+fileNameStr)
    testFileList=os.listdir('testDigits')
    errorCount=0
    mTest=len(testFileList)
    for i in range(mTest):
        fileNameStr=testFileList[i]
        fileStr=fileNameStr.split('.')[0]
        classNumStr = int(fileStr.split('_')[0])
        vectorUnderTest=photo2Vector('testDigits/'+fileNameStr)
        classfileResult=classfiy(vectorUnderTest,trainingMat,hwLabels,3)
        print('the classifier came back with',classfileResult,',the real answer is :',classNumStr)
        if(classfileResult!=classNumStr):
            errorCount+=1.0
    print('the total num of error is ',errorCount)
    print('the total error rate is ',(errorCount)/float(mTest))
handwritingClassTest()
# print(handwritingClassTest())
# mat,label=file2Matrix('datingTestSet2.txt')
# plt.figure(0)
# plt.subplot(111)
# plt.scatter(mat[:,1],mat[:,2],15.0*array(label),15.0*array(label))
# plt.show()


